﻿namespace _4_NovaAdmin.Web.Core.ServiceExtensions;

/// <summary>
/// Swagger服务
/// </summary>
public static class SwaggerSetup
{
    public static void AddSwagger(this IServiceCollection services, IConfiguration Configuration)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        services.AddSwaggerGen(c =>
        {
            // 从配置加载
            var swaggerSettings = Configuration.GetSection("SwaggerSettings").Get<SwaggerOptions>();

            // 文档信息
            c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
            {
                Title = swaggerSettings.OpenApiInfo.Title,
                Version = swaggerSettings.OpenApiInfo.Version,
                Description = swaggerSettings.OpenApiInfo.Description,
                Contact = new Microsoft.OpenApi.Models.OpenApiContact
                {
                    Name = swaggerSettings.OpenApiInfo.Contact.Name,
                    Email = swaggerSettings.OpenApiInfo.Contact.Email
                }
            });

            // XML 注释
            foreach (Assembly assembly in GlobalAssemblies.AllAssemblies)
            {
                var xmlFile = $"{assembly.GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                if (File.Exists(xmlPath))
                {
                    c.IncludeXmlComments(xmlPath, true);
                }
            }

            c.CustomOperationIds(apiDesc =>
            {
                var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
                return controllerAction.ControllerName + "-" + controllerAction.ActionName;
            });

            //TODO: 一定要返回true！
            c.DocInclusionPredicate((docName, description) => true);

            // 安全定义
            c.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme
            {
                Description = swaggerSettings.SecurityScheme.Description,
                Name = swaggerSettings.SecurityScheme.Name,
                In = Microsoft.OpenApi.Models.ParameterLocation.Header,
                Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey,
                BearerFormat = swaggerSettings.SecurityScheme.BearerFormat,
                Scheme = swaggerSettings.SecurityScheme.Scheme
            });

            // 安全需求
            c.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement
            {
                {
                    new Microsoft.OpenApi.Models.OpenApiSecurityScheme
                    {
                        Reference = new Microsoft.OpenApi.Models.OpenApiReference
                        {
                            Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme,
                            Id = swaggerSettings.SecurityRequirement.SecurityScheme.Id
                        }
                    },
                    Array.Empty<string>()
                }
            });
        });
    }
}
